Skip to content

webpack 中 loader 和 plugin 的区别

loader

loader 加载器,webpack 原生只解析 js 文件,通过 loader 解析不同格式文件。 它作用是让 webpack 拥有解析加载非 js 文件的能力, 诸如编译、压缩等,最终一起打包到指定的文件中。

  • 常见的 loader 有 babel-loader ES6 转化成 ES5 eslint-loader 通过 ESlint 检查 js tslint-loader 通过 TSLint 检查 js vue-loader 单文件方式窜写 Vue .vue sass-loader 解析 sass file-loader 文件解析成 url 路径是相对于原始文件资源,而非入口文件,根据配置将图片资源 copy 响应路径 url-loader 基于 file-loader 开发, 文件小的用 base64 替换 css-loader 解析 压缩 模块化 导入@imprt background(url) 语法 style-loader 把 css 注入到 js 中,通过 dom 操作 去加载 cache-loader 性能开销较大的 Loader 之前添加、目的是将结果缓存到磁盘里

  • loaders

plugin

plugin 是插件, 基于事件流框架 Tapable, 扩展 Webpack 功能。在 Webpack 运行的生命周期中会广播出许多事件, Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果

例如:打包之前删除原文件,打包结束后统计时长,打包后创建到到固定目录

add-asset-html-webpack-plugin 添加资源到 html compression-webpack-plugin gzip clean-webpack-plugin 删除文件 html-webpack-plugin:自动生成带入口的 index.html hard-source-webpack-plugin 二次缓存 speed-measure-webpack-plugin loader 速度分析, plugin loader 耗时 terser-webpack-plugin 压缩 js 支持压缩 ES6 webpack-bundle-analyzer 可视化输出文件体积

loader 实现

less-loader

js
// less-loader实现(经简化)
const less = require("less");

module.exports = function (content) {
  const callback = this.async(); // 转译比较耗时,采用异步方式
  const options = this.getOptions(); // 获取配置文件中less-loader的options

  less.render(
    content,
    createOptions(options), // less转译的配置
    (err, output) => {
      callback(err, output.css); // 将生成的css代码传递给下一个loader
    }
  );
};

css-loader

  • Css-loader 的作用主要是解析 css 文件中的@import 和 url 语句,处理 css-modules,并将结果作为一个 js 模块返回。

style-loader

js
// style-loader
import loaderUtils from "loader-utils";

module.exports = function (content) {
  // do nothing
};

module.exports.pitch = function (remainingRequest) {
  /*
   * 用require语句获取css-loader返回的js模块的导出
   * 用'!!'前缀跳过配置中的loader,避免重复执行
   * 用remainingRequest参数获取loader链的剩余部分,在本例中是css-loader、less-loader
   * 用loaderUtils的stringifyRequest方法将request语句中的绝对路径转为相对路径
   */
  const requestPath = loaderUtils.stringifyRequest(
    this,
    "!!" + remainingRequest
  );

  // 本例中requestPath为:
  // '!!../node_modules/css-loader/index.js!../node_modules/less-loader/dist/cjs.js!src/styles/index.less'

  return `
    const content = require(${requestPath})
    const style = document.createElement('style');
    style.innerHTML = content;
    document.head.appendChild(style);
  `;
};

参考

less-loader、css-loader、style-loader 实现原理

在 MIT 许可下发布